package com.jiangnan.view;

import com.jiangnan.filter.PcapFileFilter;
import com.jiangnan.service.PacketCutTask;
import com.jiangnan.utils.LogUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.io.File;
import java.util.Vector;

public class HomeJPanel extends JPanel {
    protected static final Logger logger = LoggerFactory.getLogger(HomeJPanel.class);
    private static final Border PADDING = BorderFactory.createEmptyBorder(10,5,10,5);
    private JFileChooser fileChooser;
    private PcapFileFilter pcapChooserFilter;
    private JTextArea textArea;
    private JComboBox<File> cmbInput;
    private JComboBox<File> cmbOutput;
    private Vector<File> cmbInputEle;
    private Vector<File> cmbOutputEle;

    private JComboBox<Integer> packetSize;
    private Vector<Integer> packetSizeEle;

    public HomeJPanel() {
        init();

        setLayout(new BorderLayout(5, 5));//设置面板 borderLayout分为东南西北中
        setBorder(new EmptyBorder(10, 10, 10, 10));

        add(initOutPane(), BorderLayout.CENTER);
        add(initCtrlPane(), BorderLayout.SOUTH);
    }

    private void init(){
        fileChooser = new JFileChooser(new File("."));
        pcapChooserFilter = new PcapFileFilter();
        fileChooser.setFileFilter(pcapChooserFilter);
    }

    private JPanel initOutPane(){
        JPanel jPanel = new JPanel(new BorderLayout(5, 5));
        JScrollPane scrollPane = new JScrollPane();
        textArea = new JTextArea();
        textArea.setRows(36);
        textArea.setToolTipText("message");
        scrollPane.setViewportView(textArea);
        scrollPane.setBorder(BorderFactory.createLineBorder(new Color(0x555555)));
        LogUtils.setLogComponent(textArea);
        jPanel.add(scrollPane, BorderLayout.CENTER);
        return jPanel;
    }

    private JPanel initCtrlPane(){
        JPanel jPanel = new JPanel(new BorderLayout(5, 5));
        JPanel optPane = new JPanel();
        optPane.setLayout(new BoxLayout(optPane,BoxLayout.Y_AXIS));
        optPane.add(initFilePane());
        optPane.add(initSettingPane());
        optPane.add(initActionPane());
        jPanel.add(optPane, BorderLayout.CENTER);
        jPanel.setBorder(BorderFactory.createLineBorder(new Color(0x555555)));
        return jPanel;
    }

    private JPanel initFilePane(){
        JPanel jPanel = new JPanel();
        jPanel.setLayout(new GridBagLayout());
        jPanel.setBorder(PADDING);
        GridBagConstraints gc = new GridBagConstraints();
        gc.insets = new Insets(10, 0, 10, 0);

        JLabel lblInputDir = new JLabel("Pcap file:");
        JButton btnInputBrowse = new JButton("Browse");
        cmbInputEle = new Vector<>();
        cmbInput = new JComboBox<>(cmbInputEle);
        cmbInput.setEditable(true);
        btnInputBrowse.addActionListener(actionEvent -> {
            fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
            fileChooser.setFileFilter(pcapChooserFilter);
            int action = fileChooser.showOpenDialog(HomeJPanel.this);
            if (action == JFileChooser.APPROVE_OPTION) {
                File inputFile = fileChooser.getSelectedFile();
                logger.debug("offline select input {}", inputFile.getPath());
                setComboBox(cmbInput, cmbInputEle, inputFile);
            }
        });

        JLabel lblOutputDir = new JLabel("Output dir:");
        JButton btnOutputBrowse = new JButton("Browse");
        cmbOutputEle = new Vector<>();
        cmbOutput = new JComboBox<>(cmbOutputEle);
        cmbOutput.setEditable(true);
        btnOutputBrowse.addActionListener(actionEvent -> {
            fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            fileChooser.removeChoosableFileFilter(pcapChooserFilter);
            int action = fileChooser.showOpenDialog(HomeJPanel.this);
            if (action == JFileChooser.APPROVE_OPTION) {
                File outputFile = fileChooser.getSelectedFile();
                logger.debug("offline select output {}", outputFile.getPath());
                setComboBox(cmbOutput, cmbOutputEle, outputFile);
            }
        });

        //first row
        gc.gridx = 0;
        gc.gridy = 0;
        gc.weightx = 0;
        gc.weighty = 0.1;
        gc.fill = GridBagConstraints.NONE;
        gc.anchor = GridBagConstraints.LINE_END;
        jPanel.add(lblInputDir, gc);

        gc.gridx = 1;
        gc.gridy = 0;
        gc.weightx = 1;
        gc.weighty = 0.1;
        gc.fill = GridBagConstraints.HORIZONTAL;
        gc.anchor = GridBagConstraints.LINE_START;
        gc.insets.left = gc.insets.right = 10;
        jPanel.add(cmbInput, gc);

        gc.gridx = 2;
        gc.gridy = 0;
        gc.weightx = 0;
        gc.fill = GridBagConstraints.NONE;
        gc.anchor = GridBagConstraints.LINE_END;
        jPanel.add(btnInputBrowse, gc);

        //second row
        gc.gridx = 0;
        gc.gridy = 1;
        gc.weightx = 0;
        gc.weighty = 0.1;
        gc.fill = GridBagConstraints.NONE;
        gc.anchor = GridBagConstraints.LINE_END;
        jPanel.add(lblOutputDir, gc);

        gc.gridx = 1;
        gc.gridy = 1;
        gc.weightx = 1;
        gc.fill = GridBagConstraints.HORIZONTAL;
        gc.anchor = GridBagConstraints.LINE_START;
        gc.insets.left = gc.insets.right = 10;
        jPanel.add(cmbOutput, gc);

        gc.gridx = 2;
        gc.gridy = 1;
        gc.weightx = 0;
        gc.fill = GridBagConstraints.NONE;
        gc.anchor = GridBagConstraints.LINE_END;
        jPanel.add(btnOutputBrowse, gc);


        return jPanel;
    }

    private JPanel initSettingPane(){
        JPanel jPanel = new JPanel();
        jPanel.setLayout(new BoxLayout(jPanel,BoxLayout.X_AXIS));
        jPanel.setBorder(PADDING);

        JLabel lbl1 = new JLabel("cut packet size:");
        packetSizeEle = new Vector<>();
        packetSizeEle.add(1000000);
        packetSize = new JComboBox<>(packetSizeEle);
        packetSize.setEditable(true);
        jPanel.add(lbl1);
        jPanel.add(packetSize);
        return jPanel;
    }


    private JPanel initActionPane() {
        JPanel jPanel = new JPanel();
        jPanel.setLayout(new BoxLayout(jPanel,BoxLayout.X_AXIS));
        jPanel.setBorder(PADDING);

        JButton btnOK = new JButton("开始");
        Dimension d = new Dimension(80,36);
        btnOK.setPreferredSize(d);
        btnOK.setMaximumSize(d);
        btnOK.setMinimumSize(d);
        jPanel.add(Box.createHorizontalGlue());
        jPanel.add(btnOK);
        jPanel.add(Box.createHorizontalGlue());
        btnOK.addActionListener(actionEvent -> {
            btnOK.setEnabled(false);
            startReadPcap();
        });

        return jPanel;
    }

    private void startReadPcap() {

        final File in;
        int cmbInIndex = cmbInput.getSelectedIndex();
        if (cmbInIndex < 0) {
            in = new File((String) cmbInput.getEditor().getItem());
        }else{
            in = cmbInputEle.get(cmbInIndex);
        }

        final File out;
        int cmbOutIndex = cmbOutput.getSelectedIndex();
        if (cmbOutIndex < 0) {
            out = new File((String) cmbOutput.getEditor().getItem());
        }else{
            out = cmbOutputEle.get(cmbOutIndex);
        }

        int packetCutSize = getComboParameter(packetSize, packetSizeEle);

        updateOut("You select: " + in.toString());
        updateOut("Out folder: " + out.toString());
        updateOut("packet cut size: " + packetCutSize);
        updateOut("-------------------------------");
        //这边要开启多线程去只想保存，不然下面程序不会执行，按钮不会变灰，日志也不会输出
        new PacketCutTask(in, out, packetCutSize).start();
    }

    private void setComboBox(JComboBox<File> combo, Vector<File> comboEle, File ele) {

        if (comboEle.contains(ele)) {
            combo.setSelectedItem(ele);
        } else {
            comboEle.addElement(ele);
            combo.setSelectedItem(comboEle.lastElement());
        }
    }

    private void updateOut(String str) {
        textArea.append(str);
        textArea.append(System.lineSeparator());
    }


    private int getComboParameter(JComboBox<Integer> param,Vector<Integer> paramEle) throws ClassCastException,NumberFormatException{
        int ret;
        int index = param.getSelectedIndex();
        String input;

        if (index < 0) {

            Object o = param.getEditor().getItem();
            if (o instanceof Integer) {
                ret = (int) o;
            } else {
                input = (String) param.getEditor().getItem();
                ret = Integer.valueOf(input);
            }
            paramEle.add(ret);

        } else {
            ret = paramEle.get(index);
        }
        return ret;
    }



}
